package de.iritgo.skillfull;


import java.util.Random;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.tiled.TiledMap;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import de.iritgo.skillfull.collision.CollisionManager;
import de.iritgo.skillfull.config.ConfigManager;
import de.iritgo.skillfull.director.Director;
import de.iritgo.skillfull.director.Sounds;
import de.iritgo.skillfull.entity.Entity;
import de.iritgo.skillfull.entity.EntityManager;
import de.iritgo.skillfull.entity.command.BarCommand;
import de.iritgo.skillfull.entity.command.MoveFieldCommand;
import de.iritgo.skillfull.entity.command.PauseCommand;
import de.iritgo.skillfull.entity.command.PlaySoundCommand;
import de.iritgo.skillfull.entity.command.SetPositionCommand;
import de.iritgo.skillfull.entity.command.SimpleTextCommand;

/**
 * The main for the slick beer game.
 * 
 * @author held
 *
 */
public class Left4Alien extends BasicGameState
{
    private TiledMap map;
    private EntityManager entityManager;
	private CollisionManager collisionManager;
	private Director director;
	static private ApplicationContext appContext;
	
	private int state;
	private int delta;
	
	public Left4Alien(int state) 
	{
		this.state = state;
	}

	/**
	 * Get the application context from spring 
	 * 
	 * @return The spring application context
	 */
	static public ApplicationContext getApplicationContext ()
	{
		return appContext;
	}
	
	/*
	 * @see org.newdawn.slick.BasicGame#init(org.newdawn.slick.GameContainer)
	 */
	public void init (GameContainer container, StateBasedGame s) throws SlickException 
	{
		container.setMouseCursor("data/wait.png", 0, 0);

		state = 2;
        container.setVSync (true);
        container.setShowFPS (true);
        map = new TiledMap("maps/BeerMap.tmx");
        
        appContext = new ClassPathXmlApplicationContext("skillfull.spring.xml");
		entityManager = (EntityManager) appContext.getBean ("de.iritgo.skillfull.EntityManager");
		collisionManager = (CollisionManager) appContext.getBean ("de.iritgo.skillfull.CollisionManager");
		director = (Director) appContext.getBean ("de.iritgo.skillfull.Director");
		
		entityManager.createCache("shot", 500);
		entityManager.createCache("explosion", 100);
		entityManager.createCache("alien1", 100);
		entityManager.createCache("alien2", 100);
		entityManager.createCache("troop", 30);
		
		// Generate the intro
		
		Entity hero = entityManager.getPrototypeEntity ("hero");
		hero.addCommand (new SetPositionCommand (hero, 1280 , 450 , false));

		hero.addCommand (new SimpleTextCommand (hero, "Grmpff !!!##!! Grrrr", 4000, false));
		for (int i = 1; i < 7; ++i)
			hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.WEST));
		hero.addCommand (new SimpleTextCommand (hero, "AHHHRR $$$$!!!## Grmpff", 4000, false));
		for (int i = 1; i < 7; ++i)
			hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.WEST));
		hero.addCommand (new SimpleTextCommand (hero, "SUU$$!!!## GRRRR $!$!$!$$$!", 4000, false));
		for (int i = 1; i < 5; ++i)
			hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.WEST));
		hero.addCommand (new SimpleTextCommand (hero, "Damn very hot desert and a shitty job...", 5000, true));
		for (int i = 1; i < 2; ++i)
			hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.SOUTH));
		
		hero.addCommand (new SimpleTextCommand (hero, ">>> Bob you must guard the beer...", 4000, true));
		hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.WEST));
		
		hero.addCommand (new SimpleTextCommand (hero, "and CONTROL the cooling system <<<, YES SIR!", 4000, true));
		hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.SOUTH));
		hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.SOUTH));
		hero.addCommand (new SimpleTextCommand (hero, "Arrgg $$!$!!$", 2000, false));
		hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.WEST));
		hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.WEST));
		hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.WEST));
		hero.addCommand (new SimpleTextCommand (hero, " and that by 50 degree", 2000, true));
		hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.NORTH));
		hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.NORTH));
		hero.addCommand (new SimpleTextCommand (hero, "Check...", 3000, true));
		hero.addCommand (new SimpleTextCommand (hero, ">>> cooling system ready... <<<", 3000, true));
		hero.addCommand (new PlaySoundCommand (Sounds.mhhBeer));
		hero.addCommand (new SimpleTextCommand (hero, "HmmmmHhmmmm?", 2000, true));
		hero.addCommand (new SimpleTextCommand (hero, "   ?", 1000, true));
		hero.addCommand (new SimpleTextCommand (hero, "COLD BEER!!!!", 2000, true));
		hero.addCommand (new PlaySoundCommand (Sounds.openBeer));

		Entity alien = entityManager.getPrototypeEntity ("alien1");
		alien.addCommand (new SetPositionCommand (alien, -32 , 450 , false));
		alien.addCommand (new PauseCommand (alien, 1000 * 29));
		for (int i = 1; i < 7; ++i)
			alien.addCommand (new MoveFieldCommand (alien, Entity.DST_FIELD.EAST));
		alien.addCommand (new SimpleTextCommand (alien, "BEEEEEERRR!", 8000, false));
		for (int i = 1; i < 7; ++i)
			alien.addCommand (new MoveFieldCommand (alien, Entity.DST_FIELD.WEST));
		
		hero.addCommand (new PauseCommand (alien, 1000 * 5));
		hero.addCommand (new SimpleTextCommand (hero, "Ohhh nooo the bugs!!!", 3000, true));
		hero.addCommand (new MoveFieldCommand (hero, Entity.DST_FIELD.WEST));
		hero.addCommand (new SimpleTextCommand (hero, "<<< COMMAND i need support!! >>>", 2000, true));
		hero.addCommand (new SimpleTextCommand (hero, ">>> Roger, reinforcements arrived 3 minutes! >>>", 2000, true));

		hero.setName ("hero");
		entityManager.addEntity (hero);
		alien.setName ("Alien-FoundBeer");
		entityManager.addEntity (alien);
		Sound music = new Sound ("sound/8bp044-04-goto80-phh.ogg");
		music.loop();
		music.play ();

		Entity health = entityManager.getPrototypeEntity ("health");
		health.addCommand (new SetPositionCommand (health, 32 , 250 , false));
		health.addCommand (new BarCommand (health, "H", 35, 350, Integer.MAX_VALUE));
		entityManager.addEntity (health);

		Entity agro = entityManager.getPrototypeEntity ("agro");
		agro.addCommand (new SetPositionCommand (agro, 70 , 250 , false));
		agro.addCommand (new BarCommand (agro, "A", 35, 20, Integer.MAX_VALUE));
		entityManager.addEntity (agro);

		Entity timeLeft = entityManager.getPrototypeEntity ("text");
		timeLeft.setName("timeLeft");
		timeLeft.addCommand (new SetPositionCommand (timeLeft, 1000 , 50 , false));

		entityManager.addEntity (timeLeft);

		Entity gameover = entityManager.getPrototypeEntity ("text");
		gameover.setName ("gameover");
		gameover.addCommand (new SetPositionCommand (gameover, (1280/2) - 100, 1024/2, false));
		entityManager.addEntity (gameover);
		container.setMouseCursor("data/cursor.png", 0, 0);
	}
	
	/**
	 * @see org.newdawn.slick.state.GameState#render(org.newdawn.slick.GameContainer, org.newdawn.slick.state.StateBasedGame, org.newdawn.slick.Graphics)
	 */
	public void update(GameContainer container, StateBasedGame arg1, int delta) throws SlickException
	{
		this.delta = delta;
		entityManager.update (container, delta);
		collisionManager.update (container, delta);
		director.update(container, delta);
	}
	
	/**
	 * @see org.newdawn.slick.state.GameState#render(org.newdawn.slick.GameContainer, org.newdawn.slick.state.StateBasedGame, org.newdawn.slick.Graphics)
	 */
	public void render(GameContainer container, StateBasedGame arg1, Graphics g) throws SlickException
	{
        map.render (0,0,0,0,100,100);
        collisionManager.render(container, g);
        entityManager.render (container, g);
        g.drawString ("Delta: " + delta, 1000, 50);
	}


	@Override
	public int getID() 
	{
		return 2;
	}
}
